(function(angular) {
	"use strict";
	angular.module("fs.waf").factory("amendmentService", amendmentService);
	amendmentService.$inject = [ "$q", "$filter", "ajaxServiceFactory", "arithService", "dateService", "formatService", "modalService", "commonService", "loanPastdueService" ];
	function amendmentService($q, $filter, ajaxServiceFactory, arithService, dateService, formatService, modalService, commonService, loanPastdueService) {

		function initDataOptions() {
			var ajaxServices = ajaxServiceFactory.buildAjaxService({
				getAmdLogOptions : {
					url : "do/cls/dataList/getAmdLogOptions",
					method : "get"
				}
			});
			var defer = $q.defer();
			ajaxServices.getAmdLogOptions().then(function(response) {
				defer.resolve(response ? response.data : {});
			});
			return defer.promise;
		}

		/**
		 * reset TierCriteria for hasSameCriteria if tierType2 isnot "N", then
		 * may be hidden hasSameCriteria if tierType2 is "N", then open all
		 * hidden first columns
		 */
		function resetHasFrontSameCriteria(intSchdList, tierType, tierType2) {
			if (!intSchdList) {
				return;
			}
			if (!tierType) {
				tierType = "N";
			}
			if (!tierType2) {
				tierType2 = "N";
			}
			// need hidden some first column criteria
			if (tierType != "N" && tierType2 != "N") {
				var lastCriteria;
				for (var i = 0; i < intSchdList.length; i++) {
					var tierCriteriaObj = intSchdList[i];
					var criteria = tierCriteriaObj.criteria;
					if (!criteria) {
						continue;
					}
					if (tierType == "T") {
						criteria = formatService.parseNumber(criteria);
					} else if (tierType == "U" || tierType == "A") {
						criteria = formatService.parseMoney(criteria);
					}
					if (i == 0) {
						lastCriteria = criteria;
						tierCriteriaObj.hasFrontSameCriteria = "N";
						continue;
					}
					//
					if (arithService.eq(criteria, lastCriteria)) {
						tierCriteriaObj.hasFrontSameCriteria = "Y";
					} else {
						tierCriteriaObj.hasFrontSameCriteria = "N";
					}
					lastCriteria = criteria;
				}
			}
			// also need open hidden first column
			else if (tierType != "N" && tierType2 == "N") {
				for (var i = 0; i < intSchdList.length; i++) {
					var tierCriteriaObj = intSchdList[i];
					tierCriteriaObj.hasFrontSameCriteria = "N";
				}
			}
		}

		/**
		 * 1.bill freq new must be greater than 0(Has exist in fw validation)
		 * 2.Bill First On Date should be equal to or greater than Effective
		 * Date.(Has exist in fw validation) 3.billFirstOnNew should be after
		 * the lock days period 4.billFirstOnNew should be 1 to 28 when
		 * frequency type is M/Q and billEndOfMonth is No 5.billFirstOnNew
		 * should not be before the last bill date TODO this want all in fw
		 * validation
		 */
		function validateBilling(amendment, messages) {
			if (amendment.uBill != "Y" || amendment.billingScheduleFlag != "Y") {
				return;
			}
			var billFirstOnNew = amendment.billFirstOnNew;
			var effectiveDate = amendment.effectiveDate;
			var lockDays = amendment.loan.loanInfo.lockDays;
			var billFreqTypeNew = amendment.billFreqTypeNew;
			var billOnEomNew = amendment.billOnEomNew;
			var nextBillDate = amendment.loan.loanExt.nextBillDate;
			var numBills = amendment.loan.loanExt.numBills;
			var lastPayDate = amendment.loan.loanExt.lastPayDate;

			// Bill First On Date should be equal to or greater than Effective
			// Date
			if (billFirstOnNew && effectiveDate && dateService.compareDate(billFirstOnNew, effectiveDate) > 0) {
				messages.push("Bill First On date should be after Effective Date");
			}

			// billFirstOnNew should be after the lock days period
			var effectiveDateTmp = angular.copy(effectiveDate);
			var loanLockEndDate = dateService.addDays(effectiveDateTmp, lockDays);
			if (billFirstOnNew && loanLockEndDate && dateService.compareDate(billFirstOnNew, loanLockEndDate) > 0) {
				messages.push("Bill First On date should be after the loan lock period");
			}

			// the bill first on should be 1 to 28 when frequency type is M/Q
			// and billEndOfMonth is No
			if ("M" == billFreqTypeNew || "Q" == billFreqTypeNew) {
				if (billOnEomNew == "N") {
					// the billFirstOnNew will be in 1 to 28 when endOfMonth
					// isn"t checked
					if (billFirstOnNew && billFirstOnNew.getDate() > 28) {
						messages.push("Bill First On date should be between 1 to 28");
					}
				}
			}

			// the bill first on should not be before the last billing date(the
			// number of bill must > 0)
			if (nextBillDate != "" && numBills * 1 > 0 && billFirstOnNew && dateService.compareDate(billFirstOnNew, nextBillDate) > 0) {
				messages.push("Bill First On date cannot be before next bill date in billing schedule.");
			}

			// billFirstOnNew need bigger lastPayDate
			if (billFirstOnNew && lastPayDate && dateService.compareDate(billFirstOnNew, lastPayDate) > 0) {
				messages.push("Bill First On date cannot be before Last Pay date.");
			}
		}

		/**
		 * if tierType2 is "N" or null, not show tier2 columns
		 */
		function resetTier2(gridOptions, tierType2) {
			if (!gridOptions) {
				return;
			}
			if (!tierType2) {
				tierType2 = "N";
			}
			if (tierType2 == "N") {
				angular.forEach(gridOptions.columnDefs, function(colDef, index) {
					if (colDef && colDef.model == "criteria2") {
						gridOptions.columnDefs.splice(index, 1);
					}
				});
			}
		}

		function formatCriteria(gridOptions, spreadTierType, tier2Flag, loanCcy, assetCcy) {
			var type = null, format = null, modelName = null;
			if (tier2Flag) {// format tier2
				modelName = "criteria2";
			} else { // format tier2
				modelName = "criteria";
			}
			if (spreadTierType == "T" // Loan Tenor
					|| spreadTierType == "Y" // Day of Mth(1-31)
					|| spreadTierType == "K" // Day of Week(1-7)
					|| spreadTierType == "H" // Month (1-12)
					|| spreadTierType == "S" // Number of Days
					|| spreadTierType == "R" // Year (yyyy)
					|| spreadTierType == "E") {// Date (yyyymmdd)
				type = "number";
				format = "integer";
			} else if (spreadTierType == "A") { // Loan Out Amt
				type = "money";
				format = loanCcy;
			} else if (spreadTierType == "U") { // Asset Amount
				type = "money";
				format = assetCcy;
			} else if (spreadTierType == "C") { // Credit Rating
				type = "percentage";
				format = "interestRate";
			}
			angular.forEach(gridOptions.columnDefs, function(colDef, index) {
				if (colDef && colDef.model == modelName) {
					colDef.type = type;
					colDef.format = format;
				}
			});
		}
		// if spreadTierType or spreadTierType2 is S(number of days), then
		// readonly has past day
		function resetIntSchdNewListReadOnly(intSchdNewList, tier2Flag, days) {
			if (tier2Flag == undefined && days == undefined) {
				// all read only
				angular.forEach(intSchdNewList, function(intSchdNew) {
					intSchdNew.pastDueFlag = true;
				});
			} else {
				if (days < 0) {
					return;
				}
				days = days + 1;
				if (intSchdNewList && intSchdNewList.length > 0) {
					angular.forEach(intSchdNewList, function(intSchdNew) {
						if (tier2Flag) { // criteria2
							if (intSchdNew.criteria2 <= days) {
								intSchdNew.pastDueFlag = true;
							}
						} else { // criteria
							if (intSchdNew.criteria <= days) {
								intSchdNew.pastDueFlag = true;
							}
						}
					});
				}
			}
		}

		/**
		 * if flag
		 * (generalFlag,obligorFlag,interestFlag,pastdueFlag,billingScheduleFlag)
		 * is N, then set New = Old
		 */
		function resetNewOld(amendment) {
			// General
			if (amendment.generalFlag == "N") {
				amendment.uMaturityDate = "N";
				amendment.maturityDateNew = amendment.maturityDateOld;
				amendment.uCustRef = "N";
				amendment.custRefNew = amendment.custRefOld;
				amendment.uPerform = "N";
				amendment.performNew = amendment.performOld;
				amendment.uPrincAmt = "N";
				amendment.princAmtNew = amendment.princAmtOld;
				amendment.princAmtChg = 0;
				amendment.uRepeatExtendFlag = "N";
				amendment.repeatExtendFlagNew = amendment.repeatExtendFlagOld;
				amendment.uRepeatExtendTenor = "N";
				amendment.repeatExtendTenorNew = amendment.repeatExtendTenorOld;
				amendment.amdComments = "";
			}
			// Obligor
			if (amendment.obligorFlag == "N") {
				amendment.uObligorCode = "N";
				amendment.obligorCodeNew = amendment.obligorCodeOld;
				amendment.obligorCodeNewOldFlag = "Y";// mark flag, if Y means
				// set new = old
				// and will not trigger obligorCodeNew changed event
				amendment.uObligorInfo = "N";
				amendment.obligorNameNew = amendment.obligorNameOld;
				amendment.obligorAddr1New = amendment.obligorAddr1Old;
				amendment.obligorAddr2New = amendment.obligorAddr2Old;
				amendment.obligorAddr3New = amendment.obligorAddr3Old;
				amendment.obligorAddr4New = amendment.obligorAddr4Old;
				amendment.obligorCityNew = amendment.obligorCityOld;
				amendment.obligorStateNew = amendment.obligorStateOld;
				amendment.obligorZipNew = amendment.obligorZipOld;
				amendment.obligorCountryNew = amendment.obligorCountryOld;
				amendment.uObligorRef = "N";
				amendment.obligorRefNew = amendment.obligorRefOld;
				amendment.uLiabAcctCode = "N";
				amendment.liabAcctTypeNew = amendment.liabAcctTypeOld;
				amendment.liabAcctCodeNew = amendment.liabAcctCodeOld;
				amendment.liabAcctNoNew = amendment.liabAcctNoOld;
				amendment.liabCustAcctIdNew = amendment.liabCustAcctIdOld;
			}
			// /Interest
			if (amendment.interestFlag == "N") {
				amendment.uBaseRate = "N";
				amendment.baseRateNew = amendment.baseRateOld;
				amendment.uSpreadRate = "N";
				amendment.spreadRateNew = amendment.spreadRateOld;
				amendment.intSchdNewList = amendment.intSchdOldList;
				amendment.uIntReview = "N";
			}
			// Past Due
			if (amendment.pastdueFlag == "N") {
				amendment.uPastdue = "N";
				amendment.pastdueSchdNewList = angular.copy(amendment.pastdueSchdOldList);
			}
			// Billing
			if (amendment.billingScheduleFlag == "N") {
				amendment.uBill = "N";
				amendment.billingFlagNew = amendment.billingFlagOld;
				amendment.billFreqTypeNew = amendment.billFreqTypeOld;
				amendment.billFreqNew = amendment.billFreqOld;
				amendment.billFirstOnNew = amendment.billFirstOnOld;
				amendment.billOnEomNew = amendment.billOnEomOld;
			}
		}

		function resetUFlag(amendment) {
			var generalFlag = false, pastDueFlag = false, obligorFlag = false, interestFlag = false, billingFlag = false;
			if (amendment.generalFlag == "Y") {
				generalFlag = generalInfoChanged(amendment);
			}
			if (amendment.obligorFlag == "Y") {
				obligorFlag = obligorInfoChanged(amendment);
			}
			if (amendment.interestFlag == "Y") {
				interestFlag = interestInfoChanged(amendment);
			}
			if (amendment.pastdueFlag == "Y") {
				pastDueFlag = pastDueInfoChanged(amendment);
			}
			if (amendment.billingScheduleFlag == "Y") {
				billingFlag = billingInfoChanged(amendment);
			}
			return generalFlag || obligorFlag || interestFlag || pastDueFlag || billingFlag;
		}

		function generalInfoChanged(amendment) {
			var result = false;
			if ((amendment.maturityDateNew && !amendment.maturityDateOld) || (!amendment.maturityDateNew && amendment.maturityDateOld)
					|| (amendment.maturityDateNew && amendment.maturityDateOld && dateService.compareDate(amendment.maturityDateNew, amendment.maturityDateOld) != 0)) {
				amendment.generalFlag = "Y";
				amendment.uMaturityDate = "Y";
				result = true;
			}

			if (amendment.custRefNew != amendment.custRefOld) {
				amendment.generalFlag = "Y";
				amendment.uCustRef = "Y";
				result = true;
			}

			if (amendment.princAmtNew != amendment.princAmtOld) {
				amendment.generalFlag = "Y";
				amendment.uPrincAmt = "Y";
				result = true;
			}
			if (!amendment.princAmtChg || amendment.princAmtChg == "0")
				amendment.uPrincAmt = "N";

			if (amendment.assetAmtNew != amendment.assetAmtOld) {
				amendment.generalFlag = "Y";
				amendment.uAssetAmt = "Y";
				result = true;
			}

			if (amendment.assetOutstdAmtNew != amendment.assetOutstdAmtOld) {
				amendment.generalFlag = "Y";
				amendment.uAssetAmt = "Y";
				result = true;
			}

			if (amendment.performNew != amendment.performOld) {
				amendment.generalFlag = "Y";
				amendment.uPerform = "Y";
				result = true;
			}
			if (amendment.repeatExtendFlagNew != amendment.repeatExtendFlagOld) {
				amendment.generalFlag = "Y";
				amendment.uRepeatExtendFlag = "Y";
				result = true;
			}
			if (amendment.repeatExtendTenorNew != amendment.repeatExtendTenorOld) {
				amendment.generalFlag = "Y";
				amendment.uRepeatExtendTenor = "Y";
				result = true;
			}
			if (amendment.amdComments) {
				amendment.generalFlag = "Y";
				result = true;
			}
			return result;
		}

		function obligorInfoChanged(amendment) {
			var result = false;
			if ($filter("encode")(amendment.obligorCodeNew) != $filter("encode")(amendment.obligorCodeOld)) {
				amendment.obligorFlag = "Y";
				amendment.uObligorCode = "Y";
				result = true;
			}

			if (amendment.obligorRefNew != amendment.obligorRefOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorRef = "Y";
				result = true;
			}

			if (amendment.obligorNameNew != amendment.obligorNameOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}

			if (amendment.obligorAddr1New != amendment.obligorAddr1Old) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.obligorAddr2New != amendment.obligorAddr2Old) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.obligorAddr3New != amendment.obligorAddr3Old) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
			}
			if (amendment.obligorAddr4New != amendment.obligorAddr4Old) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}

			if (amendment.obligorCityNew != amendment.obligorCityOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.obligorStateNew != amendment.obligorStateOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.obligorZipNew != amendment.obligorZipOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.obligorCountryNew != amendment.obligorCountryOld) {
				amendment.obligorFlag = "Y";
				amendment.uObligorInfo = "Y";
				result = true;
			}
			if (amendment.liabCustAcctIdOld != amendment.liabCustAcctIdNew) {
				amendment.obligorFlag = "Y";
				amendment.uLiabAcctCode = "Y";
				result = true;
			}
			if (amendment.liabAcctCodeNew != amendment.liabAcctCodeOld) {
				amendment.obligorFlag = "Y";
				amendment.uLiabAcctCode = "Y";
				result = true;
			}
			if (amendment.liabAcctTypeNew != amendment.liabAcctTypeOld) {
				amendment.obligorFlag = "Y";
				amendment.uLiabAcctCode = "Y";
				result = true;
			}
			if (amendment.liabAcctNoNew != amendment.liabAcctNoOld) {
				amendment.obligorFlag = "Y";
				amendment.uLiabAcctCode = "Y";
				result = true;
			}
			return result;
		}

		function interestInfoChanged(amendment) {
			var result = false;
			var intSchdOld = commonService.hash(amendment.intSchdOldList);
			var intSchdNew = commonService.hash(amendment.intSchdNewList);
			if (intSchdOld != intSchdNew) {
				amendment.interestFlag = "Y";
				amendment.uIntReview = "Y";
				result = true;
			}

			if (amendment.baseRateNew != amendment.baseRateOld) {
				amendment.uBaseRate = "Y";
				amendment.interestFlag = "Y";
				result = true;
			}
			if (amendment.spreadRateNew != amendment.spreadRateOld) {
				amendment.interestFlag = "Y";
				amendment.uSpreadRate = "Y";
				result = true;
			}
			if (amendment.cofRateNew != amendment.cofRateOld) {
				amendment.interestFlag = "Y";
				amendment.uCofRate = "Y";
				result = true;
			}
			if (amendment.insRateNew != amendment.insRateOld) {
				amendment.interestFlag = "Y";
				amendment.uInsRate = "Y";
				result = true;
			}
			if (amendment.taxRateNew != amendment.taxRateOld) {
				amendment.interestFlag = "Y";
				amendment.uTaxRate = "Y";
				result = true;
			}
			return result;
		}

		function pastDueInfoChanged(amendment) {
			var result = false;

			if (amendment.pastdueSchdNewList && amendment.pastdueSchdNewList.length > 0) {
				angular.forEach(amendment.pastdueSchdNewList, function(pastdueSchdNew) {
					// delete tempDate , because set before
					delete pastdueSchdNew.tempDate;
				});
			}
			if (amendment.pastdueSchdOldList && amendment.pastdueSchdOldList.length > 0) {
				angular.forEach(amendment.pastdueSchdOldList, function(pastdueSchdOld) {
					// delete tempDate , because set before
					delete pastdueSchdOld.tempDate;
				});
			}

			var pastdueSchd = commonService.hash(amendment.pastdueSchdOldList);
			var pastdueSchdNew = commonService.hash(amendment.pastdueSchdNewList);
			if (pastdueSchd != pastdueSchdNew) {
				amendment.pastdueFlag = "Y";
				amendment.uPastdue = "Y";
				result = true;
			}
			return result;
		}

		function billingInfoChanged(amendment) {
			var result = false;
			if (amendment.billingFlagNew != amendment.billingFlagOld) {
				amendment.billingScheduleFlag = "Y";
				amendment.uBill = "Y";
				result = true;
			}
			if (amendment.billFreqTypeNew != amendment.billFreqTypeOld) {
				amendment.billingScheduleFlag = "Y";
				amendment.uBill = "Y";
				result = true;
			}
			if (amendment.billFreqNew != amendment.billFreqOld) {
				amendment.billingScheduleFlag = "Y";
				amendment.uBill = "Y";
				result = true;
			}
			if ((amendment.billFirstOnNew && !amendment.billFirstOnOld) || (!amendment.billFirstOnNew && amendment.billFirstOnOld)
					|| (amendment.billFirstOnNew && amendment.billFirstOnOld && dateService.compareDate(amendment.billFirstOnNew, amendment.billFirstOnOld) != 0)) {
				amendment.billingScheduleFlag = "Y";
				amendment.uBill = "Y";
				result = true;
			}
			if (amendment.billOnEomNew != amendment.billOnEomOld) {
				amendment.billingScheduleFlag = "Y";
				amendment.uBill = "Y";
				result = true;
			}
			return result;
		}

		function setPastdueTenorFrom(pastdueSchdList) {
			if (pastdueSchdList && pastdueSchdList.length > 0) {
				for (var i = 0; i < pastdueSchdList.length; i++) {
					if (i == 0) {
						pastdueSchdList[i].pastdueTenorFrom = 1;
						continue;
					}
					var prePastdueTenor = pastdueSchdList[i - 1].pastdueTenor;
					var pastdueTenorFrom = arithService.add(prePastdueTenor, 1);
					pastdueSchdList[i].pastdueTenorFrom = pastdueTenorFrom;
				}
			}
		}

		// past due date had past, past due schedule read only
		function resetPastdueNewListReadOnly(pastdueSchdList, days) {
			if (days < 0) {
				return;
			}
			days = days + 1;
			if (pastdueSchdList && pastdueSchdList.length > 0) {
				angular.forEach(pastdueSchdList, function(pastdueSchd) {
					if (pastdueSchd.pastdueTenorFrom <= days) {
						pastdueSchd.readonlyFlag = true;
					}
				});
			}
		}
		
		// if loan is past due, then set read only
		function processPastDue(amendment, intSchdNewListGridOptions) {
			if (amendment.loan.loanInfo.loanStatus == "P") {
				// set default value No
				amendment.interestFlag = "N";
				amendment.obligorFlag = "N";
				amendment.generalFlag = "N";
				amendment.pastdueFlag = "N";
				amendment.billingScheduleFlag = "N";

				intSchdNewListGridOptions.enableOperation = false;
				intSchdNewListGridOptions.enableOperationRemoveSelected = false;
				if (amendment.intSchdNewList && amendment.intSchdNewList.length > 0) {
					angular.forEach(amendment.intSchdNewList, function(intSchdNew) {
						intSchdNew.pastDueFlag = true;
					});
				}
			}
		}
		
		// set date into pastdueSchd for filter
		function setpastDueSchdDate(amendment) {
			if (amendment.pastdueSchdOldList && amendment.pastdueSchdOldList.length > 0) {
				angular.forEach(amendment.pastdueSchdOldList, function(pastdueSchdOld) {
					// TODO set which date to tempDate???
					pastdueSchdOld.tempDate = amendment.amdDate;
				});
			}
		}
		
		function resetIntSchdList(amendment, intSchdNewListGridOptions, intSchdOldListGridOptions) {
			if ((!amendment.loan.loanInt.spreadTierType2 || amendment.loan.loanInt.spreadTierType2 == "N")
					&& (!amendment.loan.loanInt.spreadTierType || amendment.loan.loanInt.spreadTierType == "N")) {

				intSchdNewListGridOptions.enableOperation = false;
				intSchdNewListGridOptions.enableOperationRemoveSelected = false;
				return;
			}
			// log page, intSchdNewList = intSchdOldList
			if (amendment.intSchdNewList && amendment.intSchdNewList.length > 0) {
				// if spreadTierType2 is null or N, tier2 will not show
				resetTier2(intSchdNewListGridOptions, amendment.loan.loanInt.spreadTierType2);
				resetTier2(intSchdOldListGridOptions, amendment.loan.loanInt.spreadTierType2);

				// if the row is sub row, tier will not show
				resetHasFrontSameCriteria(amendment.intSchdNewList, amendment.loan.loanInt.spreadTierType, amendment.loan.loanInt.spreadTierType2);
				resetHasFrontSameCriteria(amendment.intSchdOldList, amendment.loan.loanInt.spreadTierType, amendment.loan.loanInt.spreadTierType2);
				// format tier
				formatCriteria(intSchdNewListGridOptions, amendment.loan.loanInt.spreadTierType, false, amendment.loan.loanInfo.loanCcy,
						amendment.loan.asset ? amendment.loan.asset.assetCcy : null);
				formatCriteria(intSchdOldListGridOptions, amendment.loan.loanInt.spreadTierType, false, amendment.loan.loanInfo.loanCcy,
						amendment.loan.asset ? amendment.loan.asset.assetCcy : null);

				// format tier2
				if (amendment.loan.loanInt.spreadTierType2 && amendment.loan.loanInt.spreadTierType2 != "N") {
					formatCriteria(intSchdNewListGridOptions, amendment.loan.loanInt.spreadTierType2, true, amendment.loan.loanInfo.loanCcy,
							amendment.loan.asset ? amendment.loan.asset.assetCcy : null);
					formatCriteria(intSchdOldListGridOptions, amendment.loan.loanInt.spreadTierType2, true, amendment.loan.loanInfo.loanCcy,
							amendment.loan.asset ? amendment.loan.asset.assetCcy : null);

				}
				// if spreadTierType or spreadTierType2 is S(number of days),
				// then readonly has past day
				if (amendment.loan.loanInt.spreadTierType == "S") {
					resetIntSchdNewListReadOnly(amendment.intSchdNewList, false, dateService.compareDate(amendment.loan.loanInfo.effectiveDate, amendment.amdDate));
				} else if (amendment.loan.loanInt.spreadTierType2 == "S") {
					resetIntSchdNewListReadOnly(amendment.intSchdNewList, true, dateService.compareDate(amendment.loan.loanInfo.effectiveDate, amendment.amdDate));
				} else {
					resetIntSchdNewListReadOnly(amendment.intSchdNewList);
					intSchdNewListGridOptions.enableOperation = false;
				}
			}
		}
		
		function setBillFirstOnNew(amendment) {
			if (amendment.billFirstOnNew && (dateService.compareDate(amendment.billFirstOnNew, amendment.billFirstOnNewTmp) != 0)) {
				if ("M" == amendment.billFreqTypeNew || "Q" == amendment.billFreqTypeNew) {
					if (amendment.billOnEomNew == "Y") {
						// the billFirstOn will be the last business day of the current selected month
						var year = amendment.billFirstOnNew.getFullYear();
						commonService.getHolidays({
							calendarYear : year
						}).then(function(objHdArry) {
							var weekEnd = {};
							var theLastDayOfMonth = dateService.getLastDayOfMonth(amendment.billFirstOnNew);
							var billFirstOnNewVal = dateService.getEeffectEndDate(theLastDayOfMonth, 0, objHdArry, weekEnd, "P");
							amendment.billFirstOnNew = dateService.parseDate(billFirstOnNewVal);
							amendment.billFirstOnNewTmp = amendment.billFirstOnNew;
						});
					}
				}
			}
		}
		
		function initTabs(amendment){
			var tabsetIndex = 0;
			if (amendment.generalFlag == "Y") {
				tabsetIndex = 0;
			} else if (amendment.obligorFlag == "Y") {
				tabsetIndex = 1;
			} else if (amendment.interestFlag == "Y") {
				tabsetIndex = 2;
			} else if (amendment.pastdueFlag == "Y") {
				tabsetIndex = 3;
			} else if (amendment.billingScheduleFlag == "Y") {
				tabsetIndex = 4;
			}
			return tabsetIndex;
		}
		
		function princAmtChgChanged(amendment){
			var amt = 0;
			if (amendment.princAmtChg) {
				amt = amendment.princAmtChg;
			}
			if (amt == 0) {
				amendment.uPrincAmt = "N";
			}
			// Outstanding Principal Amount After Amendment = loan ext"s outs amount + added principal amount
			amendment.princOutstdAmt = arithService.add(amt, amendment.loan.loanExt.princOutstdAmt);

			// Principal Amount After Amendment = loan info"s loan amount + added principal amount
			amendment.princAmtNew = arithService.add(amt, amendment.loan.loanInfo.loanAmt);
		}
		
		function obligorCodeNew(amendment){
			// if Y means set new = old and will not trigger obligorCodeNew changed event
			if (amendment.obligorCodeNewOldFlag == "Y") {
				amendment.obligorCodeNewOldFlag = "N";
				return;
			}
			amendment.liabAcctCodeNew = undefined;
			amendment.liabAcctNoNew = undefined;
		}
		
		function baseRateNewChanged(amendment){
			if (amendment.baseRateNew) {
				if (amendment.totalSpreadRateNew) {
					amendment.totalRateNew = arithService.add(amendment.baseRateNew, amendment.totalSpreadRateNew);
				} else {
					amendment.totalRateNew = amendment.baseRateNew;
				}
			}
		}
		
		function totalSpreadRateNewChanged(amendment){
			if (amendment.totalSpreadRateNew) {
				if (amendment.baseRateNew) {
					amendment.totalRateNew = arithService.add(amendment.baseRateNew, amendment.totalSpreadRateNew);
				} else {
					amendment.totalRateNew = amendment.totalSpreadRateNew;
				}
			}
		}
		
		function spreadRateNewChanged(amendment){
			if (amendment.spreadRateNew) {
				amendment.totalSpreadRateNew = amendment.spreadRateNew;
			}
		}
		
		function baseRateOldChanged(amendment){
			if (amendment.baseRateOld) {
				if (amendment.totalSpreadRateOld) {
					amendment.totalRateOld = arithService.add(amendment.baseRateOld, amendment.totalSpreadRateOld);
				} else {
					amendment.totalRateOld = amendment.baseRateOld;
				}
			}
		}
		
		function totalSpreadRateOldChanged(amendment){
			if (amendment.totalSpreadRateOld) {
				if (amendment.baseRateOld) {
					amendment.totalRateOld = arithService.add(amendment.baseRateOld, amendment.totalSpreadRateOld);
				} else {
					amendment.totalRateOld = amendment.totalSpreadRateOld;
				}
			}
		}
		
		function spreadRateOldChanged(amendment){
			if (amendment.spreadRateOld) {
				amendment.totalSpreadRateOld = amendment.spreadRateOld;
			}
		}
		
		function resetPastdueSchdList(amendment) {
			// set pastdue schedule tenor from
			setPastdueTenorFrom(amendment.pastdueSchdNewList);
			setPastdueTenorFrom(amendment.pastdueSchdOldList);
			// past due date had past, past due schedule read only
			if (amendment.pastdueDate) {
				resetPastdueNewListReadOnly(amendment.pastdueSchdNewList, dateService.compareDate(amendment.pastdueDate, amendment.amdDate));
			}
		}

		return {
			initDataOptions : initDataOptions,
			pastdueTenorChanged : loanPastdueService.pastdueTenorChanged,
			pastdueGraceChanged : loanPastdueService.pastdueGraceChanged,
			resetHasFrontSameCriteria : resetHasFrontSameCriteria,
			validateBilling : validateBilling,
			resetTier2 : resetTier2,
			formatCriteria : formatCriteria,
			resetIntSchdNewListReadOnly : resetIntSchdNewListReadOnly,
			resetSpreadTierShow : loanPastdueService.resetSpreadTierShow,
			resetNewOld : resetNewOld,
			resetUFlag : resetUFlag,
			setPastdueTenorFrom : setPastdueTenorFrom,
			resetPastdueNewListReadOnly : resetPastdueNewListReadOnly,
			processPastDue : processPastDue,
			setpastDueSchdDate : setpastDueSchdDate,
			resetIntSchdList : resetIntSchdList,
			setBillFirstOnNew : setBillFirstOnNew,
			initTabs : initTabs,
			princAmtChgChanged : princAmtChgChanged,
			obligorCodeNew : obligorCodeNew,
			baseRateNewChanged : baseRateNewChanged,
			totalSpreadRateNewChanged : totalSpreadRateNewChanged,
			spreadRateNewChanged : spreadRateNewChanged,
			baseRateOldChanged : baseRateOldChanged,
			totalSpreadRateOldChanged : totalSpreadRateOldChanged,
			spreadRateOldChanged : spreadRateOldChanged,
			resetPastdueSchdList : resetPastdueSchdList
		};
	}
})(angular);
